package com.micromall.admin;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.micromall.repository.FreightRulesMapper;
import com.micromall.repository.FreightTemplateMapper;
import com.micromall.repository.entity.FreightRules;
import com.micromall.repository.entity.FreightTemplate;
import com.micromall.service.TransactionalExecuteService;
import com.micromall.utils.ArgumentValidException;
import com.micromall.utils.Condition.Criteria;
import com.micromall.utils.Scale;
import com.micromall.utils.ValidateUtils;
import com.micromall.web.resp.ResponseEntity;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by zhangzx on 16/3/28.
 * 提现管理
 */
@RestController
@RequestMapping(value = "/admin/freight")
public class FreightTemplateController extends AdminBasicController {

	private static Logger logger = LoggerFactory.getLogger(FreightTemplateController.class);

	@Resource
	private FreightTemplateMapper       freightTemplateMapper;
	@Resource
	private FreightRulesMapper          freightRulesMapper;
	@Resource
	private TransactionalExecuteService transactionalExecuteService;

	@RequestMapping(value = "/list")
	@Transactional(readOnly = true)
	public ResponseEntity<?> list() {
		List<FreightTemplate> templates = freightTemplateMapper.selectMultiByWhereClause(Criteria.create().andEqualTo("deleted", false).build());
		for (FreightTemplate template : templates) {
			template.setFreightRulesList(
					freightRulesMapper.selectMultiByWhereClause(Criteria.create().andEqualTo("freight_id", template.getId()).build()));
		}
		return ResponseEntity.Success(templates);
	}

	@RequestMapping(value = "/get")
	@Transactional(readOnly = true)
	public ResponseEntity<?> get(int id) {
		FreightTemplate template = freightTemplateMapper.selectByPrimaryKey(id);
		if (template == null) {
			return ResponseEntity.Failure("运费模板不存在");
		}
		template.setFreightRulesList(
				freightRulesMapper.selectMultiByWhereClause(Criteria.create().andEqualTo("freight_id", template.getId()).build()));
		return ResponseEntity.Success(template);
	}

	/**
	 * @param name
	 * @param carryWay
	 * @param inclPostage
	 * @param valuationModel
	 * @param freightRules
	 * @return
	 */
	@RequestMapping(value = "/add")
	@Transactional
	public ResponseEntity<?> add(String name, String carryWay, boolean inclPostage, Integer valuationModel, String freightRules) {
		FreightTemplate template = validateParams(name, carryWay, inclPostage, valuationModel, freightRules);
		template.setDeleted(false);
		template.setCreateTime(new Date());
		transactionalExecuteService.execute(() -> {
			freightTemplateMapper.insert(template);
			for (FreightRules rules : template.getFreightRulesList()) {
				rules.setFreightId(template.getId());
				freightRulesMapper.insert(rules);
			}
		});
		return ResponseEntity.Success();
	}

	@RequestMapping(value = "/update")
	@Transactional
	public ResponseEntity<?> update(int id, String name, String carryWay, boolean inclPostage, Integer valuationModel, String freightRules) {
		FreightTemplate template = validateParams(name, carryWay, inclPostage, valuationModel, freightRules);
		template.setId(id);
		template.setUpdateTime(new Date());
		transactionalExecuteService.execute(() -> {
			freightTemplateMapper.updateByPrimaryKey(template);
			freightRulesMapper.deleteByFreightId(id);
			for (FreightRules rules : template.getFreightRulesList()) {
				rules.setFreightId(template.getId());
				freightRulesMapper.insert(rules);
			}
		});
		return ResponseEntity.Success();
	}

	private FreightTemplate validateParams(String name, String carryWay, boolean inclPostage, Integer valuationModel, String freightRules) {
		if (StringUtils.isBlank(name)) {
			throw new ArgumentValidException("运费模板名称不能为空");
		}
		if (StringUtils.isBlank(carryWay)) {
			throw new ArgumentValidException("物流公司名称不能为空");
		}
		if (ValidateUtils.illegalTextLength(1, 30, name)) {
			throw new ArgumentValidException("运费模板名称长度超过限制");
		}
		if (ValidateUtils.illegalTextLength(1, 30, carryWay)) {
			throw new ArgumentValidException("物流公司名称称长度超过限制");
		}
		List<FreightRules> freightRulesList = new ArrayList<>();
		if (!inclPostage) {
			if (valuationModel == null) {
				throw new ArgumentValidException("计价方式不能为空");
			}
			if (valuationModel != 1 && valuationModel != 2) {
				throw new ArgumentValidException("计价方式无效");
			}
			if (StringUtils.isEmpty(freightRules)) {
				throw new ArgumentValidException("计价配置不能为空");
			}
			try {
				boolean has_defaul = false;
				JSONArray jsonArray = JSON.parseArray(freightRules);
				for (int i = 0; i < jsonArray.size(); i++) {
					JSONObject jsonObject = jsonArray.getJSONObject(i);
					FreightRules rules = new FreightRules();
					rules.setFirstAmount(jsonObject.getInteger("firstAmount"));
					if (rules.getFirstAmount() < 0) {
						throw new ArgumentValidException("首费不能小于0");
					}
					rules.setSecondAmount(jsonObject.getInteger("secondAmount"));
					if (rules.getSecondAmount() < 0) {
						throw new ArgumentValidException("续费不能小于0");
					}
					rules.setDefaul(jsonObject.getBoolean("defaul"));
					if (has_defaul && rules.getDefaul()) {
						throw new ArgumentValidException("计不能设置多个默认运费");
					}
					if (rules.getDefaul()) {
						has_defaul = true;
					}
					rules.setRegion(Lists.newArrayList());
					rules.setRegionInternal(Maps.newHashMap());
					if (valuationModel == 1) {
						rules.setFirstPiece(jsonObject.getInteger("firstPiece"));
						if (rules.getFirstPiece() < 0) {
							throw new ArgumentValidException("首件不能小于0");
						}
						rules.setSecondPiece(jsonObject.getInteger("secondPiece"));
						if (rules.getSecondPiece() < 0) {
							throw new ArgumentValidException("续件不能小于0");
						}
					} else {
						rules.setFirstWeight(Scale.scale(1, jsonObject.getBigDecimal("firstWeight")));
						if (rules.getFirstWeight().doubleValue() < 0) {
							throw new ArgumentValidException("首重不能小于0");
						}
						rules.setSecondWeight(Scale.scale(1, jsonObject.getBigDecimal("secondWeight")));
						if (rules.getSecondWeight().doubleValue() < 0) {
							throw new ArgumentValidException("续重不能小于0");
						}
					}
					JSONArray region_array = jsonObject.getJSONArray("region");
					if (region_array != null) {
						for (Object o1 : region_array) {
							JSONObject province = (JSONObject)o1;
							List<String> list = Lists.newArrayList();
							for (Object o2 : province.getJSONArray("childList")) {
								JSONObject city = (JSONObject)o2;
								list.add(city.getString("name"));
							}
							rules.getRegionInternal().put(province.getString("name"), list);
							rules.getRegion().add(province);
						}
					}
					freightRulesList.add(rules);
				}
				if (!has_defaul) {
					throw new ArgumentValidException("未设置默认运费");
				}
			} catch (Exception e) {
				if (e instanceof ArgumentValidException) {
					throw e;
				}
				logger.error("", e);
				throw new ArgumentValidException("计价配置无效");
			}
		}
		FreightTemplate template = new FreightTemplate();
		template.setName(name);
		template.setCarryWay(carryWay);
		template.setInclPostage(inclPostage);
		template.setValuationModel(valuationModel);
		template.setFreightRulesList(freightRulesList);
		return template;
	}

	@RequestMapping(value = "/delete")
	@Transactional
	public ResponseEntity<?> delete(String ids) {
		if (StringUtils.isBlank(ids)) {
			throw new ArgumentValidException("参数错误");
		}
		transactionalExecuteService.execute(() -> {
			for (String id : ids.split(",")) {
				FreightTemplate template = new FreightTemplate();
				template.setId(Integer.valueOf(id));
				template.setDeleted(true);
				template.setUpdateTime(new Date());
				freightTemplateMapper.updateByPrimaryKey(template);
			}
		});
		return ResponseEntity.Success();
	}

}
